home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / libogg / libvorbis-1.0rc3 / vq / residuesplit.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-27  |  6.7 KB  |  283 lines

  1. /********************************************************************
  2.  *                                                                  *
  3.  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
  4.  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  5.  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  6.  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  7.  *                                                                  *
  8.  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
  9.  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
  10.  *                                                                  *
  11.  ********************************************************************
  12.  
  13.  function: residue backend 0 partitioner/classifier
  14.  last mod: $Id: residuesplit.c,v 1.13 2001/12/20 01:00:40 segher Exp $
  15.  
  16.  ********************************************************************/
  17.  
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <math.h>
  21. #include <stdio.h>
  22. #include "bookutil.h"
  23.  
  24. /* does not guard against invalid settings; eg, a subn of 16 and a
  25.    subgroup request of 32.  Max subn of 128 */
  26. static float _testhack(float *vec,int n){
  27.   int i,j=0;
  28.   float max=0.f;
  29.   float temp[128];
  30.   float entropy=0.;
  31.  
  32.   /* setup */
  33.   for(i=0;i<n;i++)temp[i]=fabs(vec[i]);
  34.  
  35.   /* handle case subgrp==1 outside */
  36.   for(i=0;i<n;i++)
  37.     if(temp[i]>max)max=temp[i];
  38.  
  39.   for(i=0;i<n;i++)temp[i]=rint(temp[i]);
  40.  
  41.   for(i=0;i<n;i++)
  42.     entropy+=temp[i];
  43.   return entropy;
  44.  
  45.   /*while(1){
  46.     entropy[j]=max;
  47.     n>>=1;
  48.     j++;
  49.  
  50.     if(n<=0)break;
  51.     for(i=0;i<n;i++){
  52.       temp[i]+=temp[i+n];
  53.     }
  54.     max=0.f;
  55.     for(i=0;i<n;i++)
  56.       if(temp[i]>max)max=temp[i];
  57.       }*/
  58. }
  59.  
  60. static FILE *of;
  61. static FILE **or;
  62.  
  63. /* we evaluate the the entropy measure for each interleaved subgroup */
  64. /* This is currently a bit specific to/hardwired for mapping 0; things
  65.    will need to change in the future when we get real multichannel
  66.    mappings */
  67. int quantaux(float *res,int n,float *ebound,float *mbound,int *subgrp,int parts, int subn, 
  68.          int *class){
  69.   long i,j,part=0;
  70.   int aux;
  71.  
  72.   for(i=0;i<=n-subn;i+=subn,part++){
  73.     float max=0.f;
  74.     float lentropy=0.f;
  75.  
  76.     lentropy=_testhack(res+i,subn);
  77.  
  78.     for(j=0;j<subn;j++)
  79.       if(fabs(res[i+j])>max)max=fabs(res[i+j]);
  80.  
  81.     for(j=0;j<parts-1;j++)
  82.       if(lentropy<=ebound[j] &&
  83.      max<=mbound[j] &&
  84.      part<subgrp[j])
  85.     break;
  86.     class[part]=aux=j;
  87.     
  88.     fprintf(of,"%d, ",aux);
  89.   }    
  90.   fprintf(of,"\n");
  91.  
  92.   return(0);
  93. }
  94.  
  95. int quantwrite(float *res,int n,int subn, int *class,int offset){
  96.   long i,j,part=0;
  97.   int aux;
  98.  
  99.   for(i=0;i<=n-subn;i+=subn,part++){
  100.     aux=class[part];
  101.     
  102.     for(j=0;j<subn;j++)
  103.       fprintf(or[aux+offset],"%g, ",res[j+i]);
  104.     
  105.     fprintf(or[aux+offset],"\n");
  106.   }
  107.  
  108.   return(0);
  109. }
  110.  
  111. static int getline(FILE *in,float *vec,int begin,int n){
  112.   int i,next=0;
  113.  
  114.   reset_next_value();
  115.   if(get_next_value(in,vec))return(0);
  116.   if(begin){
  117.     for(i=1;i<begin;i++)
  118.       get_line_value(in,vec);
  119.     next=0;
  120.   }else{
  121.     next=1;
  122.   }
  123.  
  124.   for(i=next;i<n;i++)
  125.     if(get_line_value(in,vec+i)){
  126.       fprintf(stderr,"ran out of columns in input data\n");
  127.       exit(1);
  128.     }
  129.   
  130.   return(1);
  131. }
  132.  
  133. static void usage(){
  134.   fprintf(stderr,
  135.       "usage:\n" 
  136.       "residuesplit <res> [<res>] <begin,n,group> <baseout> <ent,peak,sub> [<ent,peak,sub>]...\n"
  137.       "   where begin,n,group is first scalar, \n"
  138.       "                          number of scalars of each in line,\n"
  139.       "                          number of scalars in a group\n"
  140.       "         ent is the maximum entropy value allowed for membership in a group\n"
  141.       "         peak is the maximum amplitude value allowed for membership in a group\n"
  142.       "         subn is the maximum subpartiton number allowed in the group\n\n");
  143.   exit(1);
  144. }
  145.  
  146. int main(int argc, char *argv[]){
  147.   char *buffer;
  148.   char *base;
  149.   int i,j,parts,begin,n,subn,*subgrp,*class;
  150.   FILE **res;
  151.   int resfiles=0;
  152.   float *ebound,*mbound,*vec;
  153.   long c=0;
  154.   if(argc<5)usage();
  155.  
  156.   /* count the res file names, open the files */
  157.   while(!strcmp(argv[resfiles+1]+strlen(argv[resfiles+1])-4,".vqd"))
  158.     resfiles++;
  159.   if(resfiles<1)usage();
  160.  
  161.   res=alloca(sizeof(*res)*resfiles);
  162.   for(i=0;i<resfiles;i++){
  163.     res[i]=fopen(argv[i+1],"r");
  164.     if(!(res+i)){
  165.       fprintf(stderr,"Could not open file %s\n",argv[1+i]);
  166.       exit(1);
  167.     }
  168.   }
  169.  
  170.   base=strdup(argv[2+resfiles]);
  171.   buffer=alloca(strlen(base)+20);
  172.   {
  173.     char *pos=strchr(argv[1+resfiles],',');
  174.     begin=atoi(argv[1+resfiles]);
  175.     if(!pos)
  176.       usage();
  177.     else
  178.       n=atoi(pos+1);
  179.     pos=strchr(pos+1,',');
  180.     if(!pos)
  181.       usage();
  182.     else
  183.       subn=atoi(pos+1);
  184.     if(n/subn*subn != n){
  185.       fprintf(stderr,"n must be divisible by group\n");
  186.       exit(1);
  187.     }
  188.   }
  189.  
  190.   /* how many parts?... */
  191.   parts=argc-resfiles-2;
  192.   
  193.   ebound=_ogg_malloc(sizeof(float)*parts);
  194.   mbound=_ogg_malloc(sizeof(float)*parts);
  195.   subgrp=_ogg_malloc(sizeof(int)*parts);
  196.   
  197.   for(i=0;i<parts-1;i++){
  198.     char *pos=strchr(argv[3+i+resfiles],',');
  199.     subgrp[i]=0;
  200.     if(*argv[3+i+resfiles]==',')
  201.       ebound[i]=1e50f;
  202.     else
  203.       ebound[i]=atof(argv[3+i+resfiles]);
  204.  
  205.     if(!pos){
  206.       mbound[i]=1e50f;
  207.     }else{
  208.       if(*(pos+1)==',')
  209.     mbound[i]=1e50f;
  210.       else
  211.     mbound[i]=atof(pos+1);
  212.       pos=strchr(pos+1,',');
  213.       
  214.        if(pos)
  215.      subgrp[i]=atoi(pos+1);
  216.        
  217.     }
  218.     if(subgrp[i]<=0)subgrp[i]=99999;
  219.   }
  220.  
  221.   ebound[i]=1e50f;
  222.   mbound[i]=1e50f;
  223.   subgrp[i]=9999999;
  224.  
  225.   or=alloca(parts*resfiles*sizeof(FILE*));
  226.   sprintf(buffer,"%saux.vqd",base);
  227.   of=fopen(buffer,"w");
  228.   if(!of){
  229.     fprintf(stderr,"Could not open file %s for writing\n",buffer);
  230.     exit(1);
  231.   }
  232.  
  233.   for(j=0;j<resfiles;j++){
  234.     for(i=0;i<parts;i++){
  235.       sprintf(buffer,"%s_%d%c.vqd",base,i,j+65);
  236.       or[i+j*parts]=fopen(buffer,"w");
  237.       if(!or[i+j*parts]){
  238.     fprintf(stderr,"Could not open file %s for writing\n",buffer);
  239.     exit(1);
  240.       }
  241.     }
  242.   }
  243.   
  244.   vec=_ogg_malloc(sizeof(float)*n);
  245.   class=_ogg_malloc(sizeof(float)*n);
  246.   /* get the input line by line and process it */
  247.   while(1){
  248.     if(getline(res[0],vec,begin,n)){
  249.       quantaux(vec,n,ebound,mbound,subgrp,parts,subn,class);
  250.       quantwrite(vec,n,subn,class,0);
  251.  
  252.       for(i=1;i<resfiles;i++){
  253.     if(getline(res[i],vec,begin,n)){
  254.       quantwrite(vec,n,subn,class,parts*i);
  255.     }else{
  256.       fprintf(stderr,"Getline loss of sync (%d).\n\n",i);
  257.       exit(1);
  258.     }
  259.       }
  260.     }else{
  261.       if(feof(res[0]))break;
  262.       fprintf(stderr,"Getline loss of sync (0).\n\n");
  263.       exit(1);
  264.     }
  265.     
  266.     c++;
  267.     if(!(c&0xf)){
  268.       spinnit("kB so far...",(int)(ftell(res[0])/1024));
  269.     }
  270.   }
  271.   for(i=0;i<resfiles;i++)
  272.     fclose(res[i]);
  273.   fclose(of);
  274.   for(i=0;i<parts*resfiles;i++)
  275.     fclose(or[i]);
  276.   fprintf(stderr,"\rDone                         \n");
  277.   return(0);
  278. }
  279.  
  280.  
  281.  
  282.  
  283.